/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.jSkyRoom.bridge.major;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import ru.jSkyRoom.interfaces.major.Armor;
import ru.jSkyRoom.interfaces.major.Keyword;
import ru.jSkyRoom.interfaces.major.Major;
import ru.jSkyRoom.interfaces.major.Race;
import ru.jSkyRoom.interfaces.major.Spell;
import ru.jSkyRoom.interfaces.stub.EquipSlot;
import ru.jSkyRoom.interfaces.stub.ImpactSet;
import ru.jSkyRoom.interfaces.stub.JSkySound;
import ru.jSkyRoom.interfaces.stub.MaterialType;
import ru.jSkyRoom.interfaces.sub.JSkyAttackData;
import ru.jSkyRoom.interfaces.sub.JSkyBodyTemplate;
import ru.jSkyRoom.interfaces.sub.RaceGenderSettings;
import skyproc.BodyTemplate;
import skyproc.FormID;
import skyproc.RACE;
import skyproc.RACE.AttackData;
import skyproc.RACE.RACEFlags;
import skyproc.RACE.RaceFlags2;
import skyproc.genenums.ActorValue;
import skyproc.genenums.FirstPersonFlags;
import skyproc.genenums.Gender;

/**
 *
 * @author Rakev
 */
public class RaceBridge extends MajorBridge<RACE> implements Race {

    public RaceBridge(RACE adapting) {
        super(adapting);
    }

    @Override
    public boolean getFlag(RACEFlags flag) {
        return getRawObject().get(flag);
    }

    @Override
    public void setFlag(RACEFlags flag) {
        getRawObject().set(flag, true);
    }

    @Override
    public void unsetFlag(RACEFlags flag) {
        getRawObject().set(flag, false);
    }

    @Override
    public Armor getWornArmor() {
        FormID id = getRawObject().getWornArmor();
        return getFinderFactory().createArmorFinder().find(id);
    }

    @Override
    public void setArmor(Armor armor) {
        FormID id = getIdProducer().produce(armor);
        getRawObject().setWornArmor(id);
    }

    @Override
    public Collection<Spell> getSpells() {
        Collection<FormID> ids = getRawObject().getSpells();
        Collection<Spell> spells = getFinderFactory().createSpellFinder().find(ids);
        return Collections.unmodifiableCollection(spells);
    }

    @Override
    public void addSpell(Spell spell) {
        FormID id = getIdProducer().produce(spell);
        getRawObject().addSpell(id);
    }

    @Override
    public void removeSpell(Spell spell) {
        FormID id = getIdProducer().produce(spell);
        getRawObject().removeSpell(id);
    }

    @Override
    public RaceGenderSettings getRaceGenderSettings(Gender gender) {
        return new RaceGenderSettingsBridge(getRawObject(), gender);
    }

    @Override
    public float getAccelerationRate() {
        return getRawObject().getAccelerationRate();
    }

    @Override
    public void setAccelerationRate(float accelerationRate) {
        getRawObject().setAccelerationRate(accelerationRate);
    }

    @Override
    public float getAimAngleTolerance() {
        return getRawObject().getAimAngleTolerance();
    }

    @Override
    public void setAimAngleTolerance(float aimAngleTolerance) {
        getRawObject().setAimAngleTolerance(aimAngleTolerance);
    }

    @Override
    public float getAngularAcceleration() {
        return getRawObject().getAngularAcceleration();
    }

    @Override
    public void setAngularAcceleration(float angularAcceleration) {
        getRawObject().setAngularAcceleration(angularAcceleration);
    }

    @Override
    public float getAngularTolerance() {
        return getRawObject().getAngularTolerance();
    }

    @Override
    public void setAngularTolerance(float angularTolerance) {
        getRawObject().setAngularTolerance(angularTolerance);
    }

    @Override
    public float getBaseCarryWeight() {
        return getRawObject().getBaseCarryWeight();
    }

    @Override
    public void setBaseCarryWeight(float baseCarryWeight) {
        getRawObject().setBaseCarryWeight(baseCarryWeight);
    }

    @Override
    public float getBaseMass() {
        return getRawObject().getBaseMass();
    }

    @Override
    public void setBaseMass(float baseMass) {
        getRawObject().setBaseMass(baseMass);
    }

    @Override
    public float getDecelerationRate() {
        return getRawObject().getDecelerationRate();
    }

    @Override
    public void setDecelerationRate(float decelerationRate) {
        getRawObject().setDecelerationRate(decelerationRate);
    }

    @Override
    public RACE.Size getSize() {
        return getRawObject().getSize();
    }

    @Override
    public void setSize(RACE.Size size) {
        getRawObject().setSize(size);
    }

    @Override
    public float getFlightRadius() {
        return getRawObject().getFlightRadius();
    }

    @Override
    public void setFlightRadius(float flightRadius) {
        getRawObject().setFlightRadius(flightRadius);
    }

    @Override
    public float getHealthRegen() {
        return getRawObject().getHealthRegen();
    }

    @Override
    public void setHealthRegen(float healthRegen) {
        getRawObject().setHealthRegen(healthRegen);
    }

    @Override
    public float getInjuredHealthPct() {
        return getRawObject().getInjuredHealthPct();
    }

    @Override
    public void setInjuredHealthPct(float injuredHealthPct) {
        getRawObject().setInjuredHealthPct(injuredHealthPct);
    }

    @Override
    public float getMagickaRegen() {
        return getRawObject().getMagickaRegen();
    }

    @Override
    public void setMagickaRegen(float magickaRegen) {
        getRawObject().setMagickaRegen(magickaRegen);
    }

    @Override
    public float getStaminaRegen() {
        return getRawObject().getStaminaRegen();
    }

    @Override
    public void setStaminaRegen(float staminaRegen) {
        getRawObject().setStaminaRegen(staminaRegen);
    }

    @Override
    public float getStartingHealth() {
        return getRawObject().getStartingHealth();
    }

    @Override
    public void setStartingHealth(float startingHealth) {
        getRawObject().setStartingHealth(startingHealth);
    }

    @Override
    public float getStartingMagicka() {
        return getRawObject().getStartingMagicka();
    }

    @Override
    public void setStartingMagicka(float startingMagicka) {
        getRawObject().setStartingMagicka(startingMagicka);
    }

    @Override
    public float getStartingStamina() {
        return getRawObject().getStartingStamina();
    }

    @Override
    public void setStartingStamina(float startingStamina) {
        getRawObject().setStartingStamina(startingStamina);
    }

    @Override
    public float getUnarmedDamage() {
        return getRawObject().getUnarmedDamage();
    }

    @Override
    public void setUnarmedDamage(float unarmedDamage) {
        getRawObject().setUnarmedDamage(unarmedDamage);
    }

    @Override
    public float getUnarmedReach() {
        return getRawObject().getUnarmedReach();
    }

    @Override
    public void setUnarmedReach(float unarmedReach) {
        getRawObject().setUnarmedReach(unarmedReach);
    }

    @Override
    public Collection<JSkyAttackData> getAttackData() {
        Collection<AttackData> raws = getRawObject().getAttackData();
        Collection<? extends JSkyAttackData> datas = getBridgeFactory().createBridges(raws, AttackDataBridge.class);
        return Collections.<JSkyAttackData>unmodifiableCollection(datas);
    }

    @Override
    public void addAttackData(JSkyAttackData data) {
        if (data instanceof AttackDataBridge) {
            AttackData attackData = ((AttackDataBridge) data).getRawObject();
            getRawObject().addAttackData(attackData);
        } else {
            throw new IllegalArgumentException("Supported only AttackDataBridge");
        }
    }

    @Override
    public void removeAttackData(JSkyAttackData data) {
        if (data instanceof AttackDataBridge) {
            AttackData attackData = ((AttackDataBridge) data).getRawObject();
            getRawObject().removeAttackData(attackData);
        } else {
            throw new IllegalArgumentException("Supported only AttackDataBridge");
        }
    }

    @Override
    public MaterialType getMaterialType() {
        FormID id = getRawObject().getMaterialType();
        return getFinderFactory().createMaterialTypeFinder().find(id);
    }

    @Override
    public void setMaterialType(MaterialType type) {
        FormID id = getIdProducer().produce(type);
        getRawObject().setMaterialType(id);
    }

    @Override
    public ImpactSet getImpactData() {
        FormID id = getRawObject().getImpactDataSet();
        return getFinderFactory().createImpactSetFinder().find(id);
    }

    @Override
    public void setImpactData(ImpactSet data) {
        FormID id = getIdProducer().produce(data);
        getRawObject().setImpactDataSet(id);
    }

    @Override
    public Major getDecapitationFX() {
        FormID id = getRawObject().getDecapitationFX();
        return getFinderFactory().createMajorFinder().find(id);
    }

    @Override
    public void setDecapitationFX(Major fx) {
        FormID id = getIdProducer().produce(fx);
        getRawObject().setDecapitationFX(id);
    }

    @Override
    public JSkySound getOpenLootSound() {
        FormID id = getRawObject().getOpenLootSound();
        return getFinderFactory().createJSkySoundFinder().find(id);
    }

    @Override
    public void setOpenLootSound(JSkySound sound) {
        FormID id = getIdProducer().produce(sound);
        getRawObject().setOpenLootSound(id);
    }

    @Override
    public JSkySound getCloseLootSound() {
        FormID id = getRawObject().getCloseLootSound();
        return getFinderFactory().createJSkySoundFinder().find(id);
    }

    @Override
    public void setCloseLootSound(JSkySound sound) {
        FormID id = getIdProducer().produce(sound);
        getRawObject().setCloseLootSound(id);
    }

    @Override
    public EquipSlot getUnarmedEquipSlot() {
        FormID id = getRawObject().getUnarmedEquipSlot();
        return getFinderFactory().createEquipSlotFinder().find(id);
    }

    @Override
    public void setUnarmedEquipSlot(EquipSlot slot) {
        FormID id = getIdProducer().produce(slot);
        getRawObject().setUnarmedEquipSlot(id);
    }

    @Override
    public Collection<EquipSlot> getEquipSlots() {
        Collection<FormID> ids = getRawObject().getEquipSlots();
        Collection<? extends EquipSlot> slots = getFinderFactory().createEquipSlotFinder().find(ids);
        return Collections.unmodifiableCollection(slots);
    }

    @Override
    public void addEquipSlot(EquipSlot slot) {
        FormID id = getIdProducer().produce(slot);
        getRawObject().addEquipSlot(id);
    }

    @Override
    public void removeEquipSlot(EquipSlot slot) {
        FormID id = getIdProducer().produce(slot);
        getRawObject().removeEquipSlot(id);
    }

    @Override
    public Set<Keyword> getKeywords() {
        Collection<FormID> keyWordFormIds = getRawObject().getKeywordSet().getKeywordRefs();
        Collection<Keyword> keyWords = getFinderFactory().createKeywordFinder().find(keyWordFormIds);

        return Collections.unmodifiableSet(new HashSet<>(keyWords));
    }

    @Override
    public void addKeyword(Keyword keyword) {
        getRawObject().getKeywordSet().addKeywordRef(keyword.getForm());
    }

    @Override
    public void removeKeyword(Keyword keyword) {
        getRawObject().getKeywordSet().removeKeywordRef(keyword.getForm());
    }

    @Override
    public JSkyBodyTemplate getBodyTemplate(BodyTemplate.BodyTemplateType type) {
        BodyTemplate bodyTemplate = getRawObject().getBodyTemplate();
        return getBridgeFactory().createBridge(bodyTemplate);
    }

    @Override
    public boolean getFlag(BodyTemplate.GeneralFlags flag) {
        return getRawObject().getBodyTemplate().get(flag);
    }

    @Override
    public void setFlag(BodyTemplate.GeneralFlags flag) {
        getRawObject().getBodyTemplate().set(flag, true);
    }

    @Override
    public void unsetFlag(BodyTemplate.GeneralFlags flag) {
        getRawObject().getBodyTemplate().set(flag, false);
    }

    @Override
    public Race getArmorRace() {
        FormID id = getRawObject().getArmorRace();
        return getFinderFactory().createRaceFinder().find(id);
    }

    @Override
    public void setArmorRace(Race race) {
        FormID id = getIdProducer().produce(race);
        getRawObject().setArmorRace(id);
    }

    @Override
    public Race getMorphRace() {
        FormID id = getRawObject().getMorphRace();
        return getFinderFactory().createRaceFinder().find(id);
    }

    @Override
    public void setMorphRace(Race race) {
        FormID id = getIdProducer().produce(race);
        getRawObject().setMorphRace(id);
    }

    @Override
    public ActorValue getSkillBoostSkill(int boostIndex) {
        return getRawObject().getSkillBoostSkill(boostIndex);
    }

    @Override
    public int getSkillBoostValue(int boostIndex) {
        return getRawObject().getSkillBoostValue(boostIndex);
    }

    @Override
    public void setSkillBoost(int boostIndex, ActorValue skill, int value) {
        getRawObject().setSkillBoost(boostIndex, skill, value);
    }

    @Override
    public FirstPersonFlags getHeadBipedObject() {
        return getRawObject().getHeadBipedObject();
    }

    @Override
    public void setHeadBipedObject(FirstPersonFlags object) {
        getRawObject().setHeadBipedObject(object);
    }

    @Override
    public FirstPersonFlags getHairBipedObject() {
        return getRawObject().getHairBipedObject();
    }

    @Override
    public void setHairBipedObject(FirstPersonFlags object) {
        getRawObject().setHairBipedObject(object);
    }

    @Override
    public FirstPersonFlags getShieldBipedObject() {
        return getRawObject().getShieldBipedObject();
    }

    @Override
    public void setShieldBipedObject(FirstPersonFlags object) {
        getRawObject().setShieldBipedObject(object);
    }

    @Override
    public FirstPersonFlags getBodyBipedObject() {
        return getRawObject().getBodyBipedObject();
    }

    @Override
    public void setBodyBipedObject(FirstPersonFlags object) {
        getRawObject().setBodyBipedObject(object);
    }

    @Override
    public boolean getFlag(RaceFlags2 flag) {
        return getRawObject().get(flag);
    }

    @Override
    public void setFlag(RaceFlags2 flag) {
        getRawObject().set(flag, true);
    }

    @Override
    public void unsetFlag(RaceFlags2 flag) {
        getRawObject().set(flag, false);
    }

    @Override
    public Collection<String> getMovementTypeNames() {
        Collection<String> names = getRawObject().getMovementTypeNames();
        return Collections.unmodifiableCollection(names);
    }

    @Override
    public void addMovementTypeName(String name) {
        getRawObject().addMovementTypeName(name);
    }

    @Override
    public void removeMovementTypeName(String name) {
        getRawObject().removeMovementTypeName(name);
    }

    @Override
    public float getFaceGenMainClamp() {
        return getRawObject().getFaceGenMainClamp();
    }

    @Override
    public void setFaceGenMainClamp(float in) {
        getRawObject().setFaceGenMainClamp(in);
    }

    @Override
    public float getFaceGenFaceClamp() {
        return getRawObject().getFaceGenFaceClamp();
    }

    @Override
    public void setFaceGenFaceClamp(float in) {
        getRawObject().setFaceGenFaceClamp(in);
    }

    @Override
    public Race getAttackRace() {
        FormID id = getRawObject().getAttackRace();
        return getFinderFactory().createRaceFinder().find(id);
    }

    @Override
    public void setAttackRace(Race race) {
        FormID id = getIdProducer().produce(race);
        getRawObject().setAttackRace(id);
    }

}
